package com.ccx.demo.open.common.controller;

import com.ccx.demo.config.init.AppConfig;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.google.common.collect.Maps;
import com.support.annotations.AppSwaggerGroup;
import com.support.annotations.VueSwaggerGroup;
import com.support.annotations.WechatSwaggerGroup;
import com.support.mvc.entity.base.Result;
import com.support.mvc.enums.AppCode;
import com.utils.enums.Code;
import com.utils.util.CodeImage;
import com.utils.util.Util;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 验证码接口
 *
 * @author 谢长春 on 2017-9-18
 */
@Api(tags = "图片验证码")
@ApiSort(2)
@RequestMapping("/open/code")
@Controller
@Slf4j
@RequiredArgsConstructor
public class OpenCodeController {
    private final AppConfig appConfig;
    private final RedissonClient redissonClient;

//    private EmailCode emailCode;
//    private PhoneCode phoneCode;

    private Map<String, String> generateImageCode() {
        final Map<String, String> map = Maps.newHashMap();
        final String base64Image = CodeImage.ofDefault()
                .generate(code -> {
                    final String random = Util.uuid32();
                    final RBucket<String> bucket = redissonClient.getBucket(String.format("%s:%s", this.getClass().getSimpleName(), random));
                    bucket.set(code, 1, TimeUnit.DAYS);
                    map.put("random", random);
                    if (appConfig.isShowVerifyCodeEnabled()) {
                        map.put("code", code);
                    }
                })
                .base64();
        map.put("base64Image", base64Image);
        return map;
    }
    @AppSwaggerGroup
    @VueSwaggerGroup
    @WechatSwaggerGroup
    @GetMapping
    @ApiOperationSupport(order = 1, author = "谢长春")
    @ApiOperation(value = "获取图片验证码", tags = {""}, notes = "验证码图片以 base64 格式放在 data 数组中返回")
    @ResponseBody
    public Result<Map<String, String>> getImageCode() {
        return new Result<Map<String, String>>().execute(result -> result.setSuccess(generateImageCode()));
    }

    @ApiOperation(value = "校验图片验证码", tags = {"0.0.0"}, notes = "仅用于开发环境测试图片验证码输入")
    @GetMapping("/check/{random}/{code}")
    @ResponseBody
    @Deprecated
    public Result<Map<String, String>> checkImageCode(
            @ApiParam(required = true, value = "随机值", example = "random") @PathVariable String random
            , @ApiParam(required = true, value = "验证码", example = "a1b2") @PathVariable String code
    ) {
        return new Result<Map<String, String>>().execute(result -> {
            final RBucket<String> bucket = redissonClient.getBucket(String.format("%s:%s", this.getClass().getSimpleName(), random));
            if (bucket.isExists() && Objects.equals(code, bucket.get())) {
                bucket.delete();
                result.setCode(Code.A00000);
            } else { // 重新生成验证码
                result.setSuccess(generateImageCode()).setCode(AppCode.A01009);
            }
        });
    }

}
